-
Notifications
You must be signed in to change notification settings - Fork 117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extensions - Add Linux support for the Mumble plugin #1218
base: mumble-plugin
Are you sure you want to change the base?
Extensions - Add Linux support for the Mumble plugin #1218
Conversation
Mostly trailing whitespace at the end of lines
Make some of the first steps to be able to build parts of ACRE on other platforms (such as GCC). Mostly, this amounts to differences in preprocessors, and some builtins.
This allows ACRE2Core, ACRE2Shared, and ACRE2Wine to be built under Linux toolchains. We gate DirectX inclusion to Windows only; on Linux, we include FAudio as a drop in replacement for x3daudio. .pdb debugging symbols generated on the Windows build are not copied on Linux. PIC has been flipped on for Shared and Core on Linux. ACRE2Arma, ACRE2TS, ACRE2Steam, and the utility modules are not built on Linux, and it doesn't really make sense for them to be.
Some Windows types and functions have been aliased for compilation on Linux.
FilterPosition relies on x3daudio to do positional transformations. On Linux, we can use FAudio as an (almost) drop-in replacement.
Intel TBB is available as a library on Linux, under the `tbb` namespace, rather than the `concurrency` namespace as on Windows.
ACRE's config file will be stored in $XDG_CONFIG_HOME (~/.config), as per the XDG standard. Temporary files are stored in /tmp/acre-${USER}, and logs in $XDG_DATA_HOME (~/.local/share). This tends to be Linux desktop users expect.
Replace some Windows specific string functions with cross-compatible ones, and don't try to pop up message boxes on Linux.
An unused sddl.h include has also been removed
If the default path baked into the constructor is not the same as one that is later loaded, the user will end up with two config files! Only one will be used. There is no need to load the config file in the constructor, however. Hardcoded defaults are already set, and users of the class all load config files explicitly.
This is the most involved change in this changeset. On Linux, Arma runs under WINE, but Mumble is native. There's no (known to me) way to do IPC between WINE processes and native processes; WINE makes it (purposefully?) difficult. It may be possible to use Windows 10+ Unix socket compatibility (if WINE supports it), or some other mechanism. But this solution uses a simple duplex network socket listening on localhost, with a default port of 19141. The Mumble side is responsible for setting up the server, and the Arma side connects. ACRE uses Windows named pipes in "message" mode, which means rather than a stream of bytes, senders send a stream of messages and receivers receive whole messages, not partial messages. This is not the case with a TCP socket, and so a simple length encoding is used. Whenever a sender has a message to send, they first send a four byte unsigned integer that is the length of the message to come, and the receiver first reads exactly four bytes, decodes the length of the message, then reads exactly that many bytes. The code is written to be tolerant (as in: will not crash, and will simply drop the connection and wait for the otherside to reconnect) to network faults and partial sends/receives. However, given that the client and server are on the same networking stack, conditions are ideal: sends and receives should match up exactly, and faults should be impossible. Since the port chosen could conflict with another server, possibly another instance of Mumble/Acre/Arma, it is configurable. On the Mumble side, it can be configured in the ACRE config file. On the Arma side, it will be specified as a CBA setting and passed in to the extension via a parameter to callExtension.
When running in Wine, ACRE2Arma.dll will mirror the changes to NamedPipeServer.cpp for Linux; instead of using named pipes, it will connect to the socket opened on the other side. A helper function has been added to detect if running under Wine, by checking for a function Wine defines in ntdll.
Also, publish the resulting Linux/Mumble plugin
This is currently marked as WIP because ACRE2Steam currently does not search for the Linux version of Mumble to copy plugins to. Wine, by default, maps The Linux plugin will also build as 32-bit, but there's no 32-bit image of Ubuntu, and Ubuntu 22 doesn't appear to have all the multiarch packages necessary. You can view a successful CI run here: https://github.com/DylanFrese/acre2/actions/runs/2942274717 The scratch commit in that CI run has modified |
This is how I intended it, but during a rewrite/rebase it got screwed up.
As in, doesn't exist at all ? I seem to recall reading some being missing. |
I'm not 100% sure, I don't have a Ubuntu system myself to check on. I know Ubuntu 19 dropped 32-bit support to an extent. I'd went through the steps to enable multiarch in CI, and modify I'm almost certain, though, that anyone running Arma under Wine/Proton is using 64-bit. |
Ya, x86_32 support ended after *Ubuntu 18.04 LTS "Bionic Beaver" (supported until April 2023) except for a very rare few derivatives, so those packages straight up don't exist. ^ According to this 2021 comment, likely way too many 32 multiarch libs just don't exist cuz ppl don't wanna do the work, and you likely are right about 64 'Arma' under Wine/Proton mostly, so indeed it's far better to make a 64 version 1st and try to make a 32 one if it ain't too much trouble, otherwise only a 64. |
Again, to be clear, the 32-bit build works. I've built it on my system, running Debian. If there are any 32-bit users out there (which is more rare in the Linux desktop space than in the Windows space), they'd be able to build it themselves (which they're also more likely to know how to do than in the Windows space). |
I don't see a reason to support 32-bit Linux. |
The atof function is locale dependent. Specifically, it uses the locale-specific decimal separator to convert floating-point strings; that is, in a locale that uses commas as decimal separators, "0,5" will convert to 0.5, whereas "0.5" will fail, and convert as 0.0. Strings coming from Arma will always use a period as a decimal separator, this causes myriad failures. On Linux, on startup, we now set LC_NUMERIC to C, which has the behavior we want. I'm not certain why this isn't a problem on Win32. There may be a path in Qt/Mumble that sets locale one way on Linux and another on Windows.
Instead of hardcoding the filenames of the destination files for plugins, VOIPPlugin::handle_update_plugin will now use the basenames of the x32 and x64 plugins paths passed into it.
If running under Wine, ACRE2Steam will now detect that and automatically install the Linux Mumble plugin to the Linux version of Mumble, if it is present.
|
||
#define PIPE_COMMAND_OPEN 0 | ||
#define PIPE_COMMAND_CLOSE 1 | ||
#define PIPE_COMMAND_WRITE 2 | ||
#define PIPE_COMMAND_READ 3 | ||
#define PIPE_COMMAND_RESET 4 | ||
#define COMMAND_IS_WINE 99 | ||
|
||
#define WINE_SOCKET_PORT "19141" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Arbitrary; not on the https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers#Well-known_ports
if (getenv("XDG_DATA_HOME")) { | ||
acrePluginLog = std::string(getenv("XDG_DATA_HOME")) + "/" + acrePluginLog; | ||
} else { | ||
acrePluginLog = std::string(getenv("HOME")) + "/.local/share/" + acrePluginLog; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can crash if $HOME
is unset, but that should never happen, and the user probably has bigger problems if that happens.
clock_gettime(CLOCK_MONOTONIC_RAW, &t); | ||
g_pingTime = t.tv_sec; | ||
#endif | ||
vServer->sendMessage(CTextMessage::formatNewMessage("pong", "%f,", (float) g_pingTime)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MONOTIME
is more 'correct' for computing time differences, but does not track walltime. I don't think it actually matters here.
I've pushed code that now copies over the Linux .so to the user's Mumble Plugins directory when running under Wine. I depends on the environment variable As for the rest of the PR, I've taken the approach of trying to alter as little behaviour as possible when it comes to the Windows builds of the extensions, mostly because I don't use Windows and am not really able to verify the correctness of any changes. I don't have any substantial experience with C++, and so what I've written I've tried to blend in with surrounding code, but I'm sure a lot of it isn't idiomatic. I welcome a harsh review to improve it to a higher C++ standard; I simply don't know when there are better approaches available in the language or libraries. @jonpas This is ready for review. |
The Ubuntu runner builds against libtbb2, which is kind of old for newer distributions. It's not available in Debian Bookworm or Manjaro. I need to update the Ubuntu image or otherwise try to link against libtbb12 |
Make some syntactic changes for other compilers
Update CMakelists for Linux compatibility
This allows ACRE2Core, ACRE2Shared, and ACRE2Wine to be built under Linux toolchains.
Extend compat.h to provide Linux compat types
Some Windows types and functions have been aliased for compilation on Linux.
Provide FAudio/x3daudio compatibility on Linux
FilterPosition relies on x3daudio to do positional transformations. On Linux, we can use FAudio as an (almost) drop-in replacement.
Alias tbb concurrency modules on Linux
Intel TBB is available as a library on Linux, under the
tbb
namespace, rather than theconcurrency
namespace as on Windows.Update filesystem paths for building on Linux
Use paths in ~ for ACRE config & temp files
Do not load AcreSettings in constructor
If the default path baked into the constructor is not the same as one that is later loaded, the user would end up with two config files!
Reimplement NamedPipeServer on Linux
This is the most involved change in this changeset.
On Linux, Arma runs under WINE, but Mumble is native. There's no (known to me) way to do IPC between WINE processes and native processes.
This solution uses a simple duplex network socket listening on localhost, with a default port of 19141. The Mumble side is responsible for setting up the server, and the Arma side connects.
Modify arma2ts to use sockets if running in Wine
When running in Wine, ACRE2Arma.dll will mirror the changes to NamedPipeServer.cpp for Linux; instead of using named pipes, it will connect to the socket opened on the other side.
Add a Linux build job to CI
Also, publish the resulting Linux/Mumble plugin
This PR adds support for building the ACRE Mumble plugin for native Linux, and modifies both it and the arma2ts DLL (when running in WINE) to communicate over network sockets instead of named pipes.
I've polished the commit log so that this changeset may be reviewed in a developmental manner on the command line with
git log -w -p --reverse origin/mumble-plugin..HEAD
, rather than as one big diff (if you prefer).I've also added and tested CI support (although I haven't tested the publishing steps, for obvious reasons) for the Linux plugin. CI has built this workshop item, if you'd like to test it.